using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static partial class ReferencePool
{
    private sealed class ReferenceCollection
    {
        private readonly Queue<IReference> _references;

        private readonly Type _referenceType;

        /// <summary>
        /// 被获取的数量
        /// </summary>
        private int _acquireReferenceCount;

        /// <summary>
        /// 自动添加次数
        /// </summary>
        private int _addReferenceCount;

        /// <summary>
        /// 回收次数
        /// </summary>
        private int _recycleReferenceCount;

        /// <summary>
        /// 正在被使用的次数
        /// </summary>
        private int _usingReferenceCount;

        public ReferenceCollection(Type referenceType)
        {
            _referenceType = referenceType;
            _acquireReferenceCount = 0;
            _references= new Queue<IReference>();
        }

        /// <summary>
        /// 获取引用类型
        /// </summary>
        public Type ReferenceType
        {
            get { return _referenceType; }
        }

        /// <summary>
        /// 被获取的次数
        /// </summary>
        public int AcquireReferenceCount
        {
            get { return _acquireReferenceCount; }
        }

        public int AddReferenceCount
        {
            get { return _addReferenceCount; }
        }

        public T Acquire<T>() where T : IReference, new()
        {
            if(typeof(T)!= _referenceType)
            {
                throw new Exception($"类型不匹配{typeof(T)}---{_referenceType}");
            }

            _usingReferenceCount++;
            _acquireReferenceCount++;
            lock (_references)
            {
                if(_references.Count > 0)
                {
                    return (T)_references.Dequeue();
                }
            }

            _addReferenceCount++;
            return new T();
        }

        public void Recycle(IReference reference)
        {
            reference.Clear();
            lock (_references)
            {
                _references.Enqueue(reference);
            }

            _recycleReferenceCount++;
            _usingReferenceCount--;
        }

        /// <summary>
        /// 引用池释放
        /// </summary>
        public void Release()
        {
            if (_references == null || _references.Count == 0)
                return;

            foreach(IReference reference in _references)
            {
                reference.Clear();
            }
        }
    }
}
